package com.baosight.risk.service.xtzy.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baosight.risk.api.xtzy.IXtsqMenuAuthoService;
import com.baosight.risk.base.mapper.BaseMapper;
import com.baosight.risk.base.redis.BaseRedis;
import com.baosight.risk.base.service.BaseServiceImpl;
import com.baosight.risk.common.bean.BeanUtils;
import com.baosight.risk.common.utils.StringUtils;
import com.baosight.risk.mapper.system.SysMenuMapper;
import com.baosight.risk.mapper.system.SysRoleMapper;
import com.baosight.risk.mapper.xtzy.XtsqMenuAuthoMapper;
import com.baosight.risk.mapper.xtzy.XtzyCompRoleMapper;
import com.baosight.risk.mapper.xtzy.XtzyCompanyMapper;
import com.baosight.risk.mapper.xtzy.XtzyRoleUserMapper;
import com.baosight.risk.service.system.entity.SysMenu;
import com.baosight.risk.service.system.entity.SysRole;
import com.baosight.risk.service.xtzy.entity.XtsqMenuAutho;
import com.baosight.risk.service.xtzy.entity.XtzyCompRole;
import com.baosight.risk.service.xtzy.entity.XtzyCompany;
import com.baosight.risk.service.xtzy.entity.XtzyRoleUser;
import com.baosight.risk.service.xtzy.entity.XtzyUser;
import com.baosight.risk.service.xtzy.vo.XtzyCompanyVO;

import lombok.extern.slf4j.Slf4j;

/**
 * 类 名: XtsqMenuAuthoServiceImpl
 * 作 者: 黎秋荣
 * 创 建：2019年05月21日
 * 版 本：v2.2.0
 * 历 史: (版本) 作者 时间 注释
 */
@Service
@Slf4j
public class XtsqMenuAuthoServiceImpl extends BaseServiceImpl<XtsqMenuAutho> implements IXtsqMenuAuthoService {

    @Autowired
    private XtsqMenuAuthoMapper menuAuthoMapper;
    @Autowired
    private XtzyRoleUserMapper roleUserMapper;
    @Autowired
    private SysRoleMapper roleMapper;
    @Autowired
    private SysMenuMapper menuMapper;
    @Autowired
    private XtzyCompRoleMapper compRoleMapper;
    @Autowired
    private XtzyCompanyMapper companyMapper;
    @Autowired
    private BaseRedis redis;

    @Override
    public BaseMapper getMapper() {
        return menuAuthoMapper;
    }


    @Override
    public List<SysRole> getRoleByCompId(String compId, String roleName, String flag) {
        //根据组织的公司类别判断，如果是公司，查所有部门，如果是其他的，查看上级公司所选择的角色
        //如果标识是1，是查询列表页，如是是2，是弹框页面
        if ("1".equals(flag)) {
            return compRoleMapper.getRoleByCompId(compId, roleName);
        }
        List<SysRole> list = new ArrayList<>();
        XtzyCompany company = companyMapper.selectByPrimaryKey(compId);
        if ("1".equals(company.getCompType())) {
            //查所有部门
            SysRole role = new SysRole();
            if (StringUtils.isNotEmpty(roleName)) {
                role.setRoleKey(roleName);
            }
            role.setStatus("10");
            list = roleMapper.selectRole(role);
        } else {
            //找到上级公司的编码
            company = companyMapper.getCompByCompCode(company.getPathCode());
            //查看上级公司所选择的角色
            list = compRoleMapper.getRoleByCompId(company.getCompCode(), roleName);
        }
        return list;
    }

    @Override
    public Integer deleteRoleAuthById(String id) throws Exception {
        //先查询该单位该角色有没有被人员选择，如果被选择，则不可以删除
        XtzyCompRole compRole = compRoleMapper.selectByPrimaryKey(id);
        if (null == compRole) {
            log.error("数据有误！不可删除");
            throw new Exception("数据有误！不可删除");
        }
        //根据单位和角色去找授权关系，查询是否被人选择，如果已经被选择，不可以删除
        List<XtzyRoleUser> roleUserList = roleUserMapper.getByCompIdAndRoleId(compRole.getCompId(), compRole.getRoleId());
        if (CollectionUtils.isNotEmpty(roleUserList)) {
            log.error("已经有人员选择了该角色，不可删除！");
            throw new Exception("已经有人员选择了该角色，不可删除！");
        }
        //删除角色及授权关系
        menuAuthoMapper.deleteByRoleIdAndCompId(compRole.getRoleId(), compRole.getCompId());
        //删除单位下的该角色
        return compRoleMapper.deleteByPrimaryKey(id);
    }


    @Override
    public Integer addRoleByCompCode(XtzyCompanyVO companyVO) throws Exception {
        XtzyCompany company = companyMapper.selectByPrimaryKey(companyVO.getCompCode());
        for (SysRole role : companyVO.getRoleList()) {
            //先判断当前组织下是否已经有该角色，如果有，返回
            XtzyCompRole xtzyCompRole = compRoleMapper.queryRoleByCompIdAndRoleId(company.getCompCode(), role.getId());
            if (null == xtzyCompRole) {
                //新增
                XtzyCompRole compRole = new XtzyCompRole();
                compRole.setRoleId(role.getId());
                compRole.setRoleCode(role.getRoleKey());
                compRole.setRoleDesc(role.getRoleName());
                compRole.setCompId(company.getId());
                compRole.setCompCode(company.getCompCode());
                compRole.setCompName(company.getCompName());
                compRole.setPathCode(company.getPathCode());
                compRole.setPathName(company.getPathName());
                compRole = (XtzyCompRole) BeanUtils.initBean(compRole);
                compRoleMapper.insert(compRole);
            } else {
                log.error(company.getCompName() + "=该单位下已经存在【" + role.getRoleName() + "】角色！");
                throw new Exception(company.getCompName() + "=该单位下已经存在【" + role.getRoleName() + "】角色！");
            }
        }
        return 1;
    }


    @Override
    public List<SysRole> queryRoleByCompId(String compId, String topCompId) {
        if (topCompId == null) {
            XtzyCompany company = companyMapper.selectByPrimaryKey(compId);
            XtzyCompany topCompany = companyMapper.getTopCompany(company.getPathCode(), Short.parseShort("2"));

            if (topCompany == null) {
                topCompId = compId;
            } else {
                if (topCompany.getId().equals(company.getId())) {
                    topCompId = "BGTA";
                } else {
                    topCompId = topCompany.getId();
                }
            }
        }

        List<SysRole> list = getRoleByCompId(compId, null, "1");
        if (CollectionUtils.isEmpty(list)) {
            list = getRoleByCompId(topCompId, null, "1");
        } else {
            list.addAll(getRoleByCompId(topCompId, null, "1"));
        }
        servicePage();
        return list;
    }


    @Override
    public List<SysMenu> getMenuByCompAndUser(String compId, XtzyUser user) {
        //根据组织和用户查找所有的角色
        List<XtzyRoleUser> roleUserList = roleUserMapper.getRoleByCompIdAndUserId(compId, user.getId());
        if (CollectionUtils.isEmpty(roleUserList)) {
            return null;
        }
        //根据组织和角色查找所有菜单；
//        List<String> roleIds = roleList.stream().map(SysRole::getId).collect(Collectors.toList());
//        return menuMapper.getMenuByCompIdAndRoleIds(compId, roleIds);
//        List<XtsqMenuAutho> authoList = menuAuthoMapper.getByCompIdAndRoleIds(compId,roleIds);
        List<XtsqMenuAutho> authoList = new ArrayList<>();
        for (XtzyRoleUser roleUser : roleUserList) {
            List<XtsqMenuAutho> a = menuAuthoMapper.getByCompIdAndRoleId(roleUser.getRoleCompCode(), roleUser.getRoleCode());
            authoList.addAll(a);
        }
        List<SysMenu> menuList = new ArrayList<>();
        List<String> menuCodeList = new ArrayList<>();
        Map<String, String> authMap = new HashMap<>();
        Map<String, List<XtsqMenuAutho>> menuCodes = authoList.stream().collect(Collectors.groupingBy(XtsqMenuAutho::getMenuCode));
        for (String menuCode : menuCodes.keySet()) {
            List<XtsqMenuAutho> menus = menuCodes.get(menuCode);
            String code = "";
            String auth = "";
            if (menus.size() > 1) {
                //判断数据权限，取最大的
                for (XtsqMenuAutho menu : menus) {
//                    if ("ALL".equals(menu.getAuthoCode())){
//                        code = menu.getMenuCode();
//                        auth = menu.getAuthoCode();
//                        break;
//                    }else if ("COMP".equals(menu.getAuthoCode())){
//                        code = menu.getMenuCode();
//                        auth = menu.getAuthoCode();
//                        break;
//                    }else {
//                        code = menu.getMenuCode();
//                        auth = menu.getAuthoCode();
//                        break;
//                    }
                    code = menu.getMenuCode();
                    auth = menu.getAuthoCode();
                }
            } else {
                code = menus.get(0).getMenuCode();
                auth = menus.get(0).getAuthoCode();
            }
            if (StringUtils.isEmpty(auth)) {
                auth = "ALL";
            }
            menuCodeList.add(code);
            authMap.put(code, auth);
        }
        List<SysMenu> sysMenuList = menuMapper.queryMenuByIds(menuCodeList);
        if (CollectionUtils.isNotEmpty(sysMenuList)) {
            for (SysMenu sysMenu : sysMenuList) {
                sysMenu.setExt5(authMap.get(sysMenu.getId()));
            }
        }
        return sysMenuList;
    }

    @Override
    public List<SysRole> getRole() {
        return roleMapper.queryRole();
    }


    @Override
    public List<SysMenu> getMenuByRoleId(String roleId) {
        List<String> menuIds = menuAuthoMapper.getMenuByRoleId(roleId);
        if (CollectionUtils.isEmpty(menuIds)) {
            return null;
        }
        return menuMapper.queryMenuByIds(menuIds);
    }

    @Override
    public List<SysMenu> getMenuByRoleIdAndCompId(String compId, String roleId) {
        List<SysMenu> sysMenus = menuMapper.getMenuByRoleIdAndCompId(compId, roleId);
        return sysMenus;
    }


    @Override
    public Integer inserCompRole(XtzyCompanyVO companyVO) {
        redis.deleteList("auth:");
        for (XtzyCompany company : companyVO.getCompanyList()) {
            List<SysRole> roleList = compRoleMapper.getRoleByCompId(companyVO.getId(), null);
            if (!CollectionUtils.isEmpty(roleList)) {
                //直接新增
                //已存在数据
                List<String> roleIds1 = roleList.stream().map(SysRole::getId).collect(Collectors.toList());
                //传进来的数据
                List<String> roleIds2 = companyVO.getRoleList().stream().map(SysRole::getId).collect(Collectors.toList());
                //需要删除的数据
                List<String> deleteRoleIds = new ArrayList<>();
                for (String id : roleIds1) {
                    //如果数据库已存在的数据不包含在传进来的数据中，代表已经删除
                    if (!roleIds2.contains(id)) {
                        deleteRoleIds.add(id);
                    }
                }
                if (!CollectionUtils.isEmpty(deleteRoleIds)) {
                    for (String roleId : deleteRoleIds) {
                        //根据需要的数据删除
                        compRoleMapper.deleteByCompIdAndRoleId(company.getId(), roleId);
                        //删除组织、人员、角色关系
                        roleUserMapper.deleteByCompIdAndRoleId(company.getId(), roleId);
                    }
                }
            }
            //正常添加数据
            insertCompRoleinfo(company, companyVO.getRoleList(), roleList);
        }
        return 1;
    }


    public void insertCompRoleinfo(XtzyCompany company, List<SysRole> roleList, List<SysRole> oldRoles) {
        for (SysRole role : roleList) {
            XtzyCompRole compRole = new XtzyCompRole();
            if (oldRoles.stream().map(SysRole::getId).collect(Collectors.toList()).contains(role.getId())) {
                continue;
            }
            //如果ID不为空，代表数据已存在，不做操作，如果不存在，新增
//            if (StringUtils.isEmpty(compRole.getId())){
//               continue;
//            }
            compRole.setRoleId(role.getId());
            compRole.setRoleCode(role.getRoleKey());
            compRole.setCompId(company.getId());
            compRole.setCompCode(company.getCompCode());
            compRole.setCompName(company.getCompName());
            compRole.setPathCode(company.getPathCode());
            compRole.setPathName(company.getPathName());
            compRole = (XtzyCompRole) BeanUtils.initBean(compRole);
            compRoleMapper.insert(compRole);
        }
    }


    @Override
    public Integer inserMenuByRole(XtzyCompanyVO companyVO) {
        redis.deleteList("auth:");
        for (SysRole role : companyVO.getRoleList()) {
            //根据组织和用户删除==组织、角色、菜单关系
            menuAuthoMapper.deleteByRoleIdAndCompId(role.getId(), companyVO.getId());
            //添加数据
            for (SysMenu menu : companyVO.getMenuList()) {
                //根据机构、角色、菜单往关系表中插入数据
                XtsqMenuAutho autho = new XtsqMenuAutho();
                autho = (XtsqMenuAutho) BeanUtils.initBean(autho);
                autho.setCompCode(companyVO.getId());
                autho.setCompName(companyVO.getCompName());
                autho.setMenuCode(menu.getId());
                autho.setMenuName(menu.getMenuName());
                autho.setRoleCode(role.getId());
                autho.setRoleName(role.getRoleName());
                // 添加权限节点名称信息。Ext1权限代码，Ext2权限名称
                autho.setAuthoCode(menu.getExt1());
                autho.setAuthoName(menu.getExt2());
                menuAuthoMapper.insert(autho);
            }
        }
        return 1;
    }

}
